Skip to content

Add ExtensionFilter API to extensions#3650

Open
liamawhite wants to merge 4 commits intoistio:masterfrom
liamawhite:extension-filter
Open

Add ExtensionFilter API to extensions#3650
liamawhite wants to merge 4 commits intoistio:masterfrom
liamawhite:extension-filter

Conversation

@liamawhite
Copy link
Member

@liamawhite liamawhite commented Feb 12, 2026

Please provide a description of this PR:

Adds native support for Lua filters as described in the following design doc.

Related implementation PR is here.

@liamawhite liamawhite requested a review from a team as a code owner February 12, 2026 17:30
@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Feb 12, 2026
@istio-policy-bot
Copy link

😊 Welcome @liamawhite! This is either your first contribution to the Istio api repo, or it's been
a while since you've been here.

You can learn more about the Istio working groups, Code of Conduct, and contribution guidelines
by referring to Contributing to Istio.

Thanks for contributing!

Courtesy of your friendly welcome wagon.

@istio-testing istio-testing added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Feb 12, 2026
- Move top-level TrafficSelector to extension_filter.proto
- Keep WasmPlugin.TrafficSelector nested for backward compat
- Remove targetRef from ExtensionFilter
- Add release notes
@istio-policy-bot istio-policy-bot added the lifecycle/stale Indicates a PR or issue hasn't been manipulated by an Istio team member for a while label Mar 17, 2026
@istio-policy-bot istio-policy-bot removed the lifecycle/stale Indicates a PR or issue hasn't been manipulated by an Istio team member for a while label Mar 17, 2026
@liamawhite liamawhite changed the title [WIP] Add ExtensionFilter API to extensions Add ExtensionFilter API to extensions Mar 17, 2026
@liamawhite liamawhite removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Mar 17, 2026
// +cue-gen:ExtensionFilter:storageVersion
// +cue-gen:ExtensionFilter:annotations:helm.sh/resource-policy=keep
// +cue-gen:ExtensionFilter:labels:app=istio-pilot,chart=istio,heritage=Tiller,release=istio
// +cue-gen:ExtensionFilter:subresource:status
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we really going to write status to this? Or is the idea to just have it in case?

Copy link
Member Author

@liamawhite liamawhite Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing WASMPlugin API has validation written to status for things like missing URL, similar logic here. No conditions though by the looks of it.

repeated TrafficSelector match = 6;

// WebAssembly filter configuration. Mutually exclusive with `lua`.
WasmConfig wasm = 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not use a oneof here? It would also be good to have some documentation somewhere (not necessarily here) saying that admins who want to disallow certain types can deploy a VAP (and then provide a sample VAP)

Copy link
Member Author

@liamawhite liamawhite Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see both oneof and CEL verification across the api and its not clear to me why to use one vs the other so I went with what the WASMPlugin API already did. Maybe CEL validation is used when there are back compat problems (if fields are added later)?

I tried with oneof and it seemed to generate everything fine so I guess that's preferable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@howardjohn can correct me if I'm wrong but I think oneoef is preferable for new APIs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its probably good to use a oneof but it doesn't practically matter since its not user facing

repeated TrafficSelector match = 6;

// WebAssembly filter configuration. Mutually exclusive with `lua`.
WasmConfig wasm = 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the skip in field numbers?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen it in other places in the API where some numbers are skipped to leave place for additional fields later. I think the argument is that its easy to keep track of what numbers are used if the fields are always increasing?

I can change it though if you want?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah let's keep it sequential; I think the reason for other apis skipping is past changes

// that defines the appropriate callback functions (`envoy_on_request` and/or
// `envoy_on_response`).
//
// The maximum size is 64KB. For larger or more complex filters, use a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this enforced by the proxy or the control plane? Any way k8s could validate for us?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 64kb limit is somewhat arbitrary but overall size does have an impact on LDS response size and how much memory each proxy consumes (AFAICT envoy loads the script into memory once per worker thread). The only actual limit I can think of is the limit imposed by etcd, which I believe is 2mb?

What would you recommend we do here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big +1 on starting with the limit. Let's just make sure we enforce it somewhere

// metadata, and other request/response attributes. See the Envoy Lua filter
// documentation for the complete API:
// https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter
message LuaConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we decide if/how this CRD would/would not interact with per-route overrides?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do we support loading lua from a file with EnvoyFilter? Should we support it here?

…mment

- Renumber ExtensionFilter fields to be contiguous (targetRefs=2, phase=3, priority=4, match=5)
- Wrap wasm/lua in oneof filter_config for type-safe mutual exclusion
- Clarify priority tiebreaker ordering (creationTimestamp, then name/namespace)
- Regenerate pb.go, pb.html, and CRD YAML
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants